package com.iwithlong.service.impl;

import com.imesne.assistant.common.bean.BeanKit;
import com.imesne.assistant.common.exception.ImesneException;
import com.imesne.assistant.common.page.PageList;
import com.imesne.assistant.common.validation.Verifier;
import com.imesne.assistant.jdbc.command.entity.Select;
import com.imesne.assistant.jdbc.persist.JdbcDao;
import com.iwithlong.context.ResultConst;
import com.iwithlong.entity.*;
import com.iwithlong.enums.*;
import com.iwithlong.event.MemberEvent;
import com.iwithlong.service.ActivityEnrollService;
import com.iwithlong.service.ActivityService;
import com.iwithlong.service.IndexService;
import com.iwithlong.utils.DistanceUtils;
import com.iwithlong.utils.IndexUtils;
import com.iwithlong.utils.LuceneContext;
import com.iwithlong.vo.*;
import com.ktanx.platform.utils.HttpUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.*;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created by xiexiaohan on 2017/10/10.
 */
@Service
@Transactional
public class ActivityServiceImpl implements ActivityService{
    @Resource
    JdbcDao jdbcDao;

    @Resource
    IndexService indexService;

    @Resource
    ActivityEnrollService activityEnrollService;

    @Resource
    private ApplicationContext applicationContext;

    @Override
    public PageList<ActivityVo> pageList(ActivityVo activityVo) {
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        if(StringUtils.isNotBlank(activityVo.getKeyword())){
            activitySelect.and().begin()
                    .condition("name","like",new Object[]{"%"+activityVo.getKeyword()+"%"})
                    .or("brief","like",new Object[]{"%"+activityVo.getKeyword()+"%"})
                    .or("content","like",new Object[]{"%"+activityVo.getKeyword()+"%"})
                    .or("activityLabel","like",new Object[]{"%"+activityVo.getKeyword()+"%"})
                    .end();
        }
        if(StringUtils.isNotBlank(activityVo.getCreator())){
            activitySelect.and("creator",activityVo.getCreator());
        }
        if(StringUtils.isNotBlank(activityVo.getModifier())){
            activitySelect.and("modifier",activityVo.getModifier());
        }
        if(StringUtils.isNotBlank(activityVo.getAuditor())){
            activitySelect.and("auditor",activityVo.getAuditor());
        }
        if(StringUtils.isNotBlank(activityVo.getIssuer())){
            activitySelect.and("issuer",activityVo.getIssuer());
        }
        if(StringUtils.isNotBlank(activityVo.getStatus())){
            activitySelect.and("status",activityVo.getStatus());
        }
        if(StringUtils.isNotBlank(activityVo.getEnableSearch())){
            activitySelect.and("enable",activityVo.getEnableSearch());
        }
        if(activityVo.getActivityAreaVo()!=null&&StringUtils.isNotBlank(activityVo.getActivityAreaVo().getAreaName())){
            Select<ActivityArea> activityAreaSelect = jdbcDao.createSelect(ActivityArea.class).where("1",1);
            activityAreaSelect.and("areaName",activityVo.getActivityAreaVo().getAreaName());
            ActivityArea activityArea = activityAreaSelect.singleResult();
            if(activityArea!=null){
                activitySelect.and("activityAreaId",activityArea.getActivityAreaId());
            }
        }
        if(activityVo.getBeginDateStart()!=null){
            activitySelect.and("beginDate",">=",new Object[]{activityVo.getBeginDateStart()});
        }
        if(activityVo.getBeginDateEnd()!=null){
            activitySelect.and("beginDate","<=",new Object[]{activityVo.getBeginDateEnd()});
        }
        if(activityVo.getEndDateStart()!=null){
            activitySelect.and("endDate",">=",new Object[]{activityVo.getEndDateStart()});
        }
        if(activityVo.getEndDateStart()!=null){
            activitySelect.and("endDate","<=",new Object[]{activityVo.getEndDateEnd()});
        }
        if(activityVo.getRecommendedStart()!=null){
            activitySelect.and("recommended",">=",new Object[]{activityVo.getRecommendedStart()});
        }
        if(activityVo.getRecommendedEnd()!=null){
            activitySelect.and("recommended","<=",new Object[]{activityVo.getRecommendedEnd()});
        }
        if(StringUtils.isNotBlank(activityVo.getOrderBy())){
            if(StringUtils.equals(activityVo.getOrderByType(),"asc")){
                activitySelect.orderBy(activityVo.getOrderBy()).asc();
            }else if(StringUtils.equals(activityVo.getOrderByType(),"desc")){
                activitySelect.orderBy(activityVo.getOrderBy()).desc();
            }
        }else {
            activitySelect.orderBy("gmtModify").desc();
        }
        PageList<Activity> activities = activitySelect.pageList(activityVo);
        List<ActivityVo> activityVos = BeanKit.convert(ActivityVo.class,activities);
        for(ActivityVo activityVo1:activityVos){
            setActivityUploadFiles(activityVo1);
            Select<ActivityArea> activityAreaSelect = jdbcDao.createSelect(ActivityArea.class).where("1",1);
            activityAreaSelect.and("activityAreaId",activityVo1.getActivityAreaId());
            activityVo1.setActivityAreaVo(BeanKit.convert(new ActivityAreaVo(),activityAreaSelect.singleResult()));
        }
        PageList<ActivityVo> result = new PageList<>(activityVos,activities.getPager());
        return result;
    }

    @Override
    public ActivityVo findById(Long activityId) {
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        activitySelect.and("activityId",activityId);
        Activity activity = activitySelect.singleResult();
        ActivityVo activityVo = BeanKit.convert(new ActivityVo(),activity);
        if(activity.getActivityAreaId()!=null){
            Select<ActivityArea> activityAreaSelect = jdbcDao.createSelect(ActivityArea.class).where("1",1);
            activityAreaSelect.and("activityAreaId",activity.getActivityAreaId());
            ActivityArea activityArea = activityAreaSelect.singleResult();
            activityVo.setActivityAreaVo(BeanKit.convert(new ActivityAreaVo(),activityArea));
        }
        setActivityUploadFiles(activityVo);
        return activityVo;
    }

    @Override
    public Map<String,Object> interest(Long activityId, String weixin, boolean isInterest) {
        Map<String,Object> result = new HashMap<>();
        Verifier.init().notEmpty(weixin,"微信id").validate();
        Select<Interest> interestSelect = jdbcDao.createSelect(Interest.class).where("1",1);
        interestSelect.and("owner",weixin);
        interestSelect.and("activityId",activityId);
        Interest interest = interestSelect.singleResult();
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        activitySelect.and("activityId",activityId);
        Activity activity = activitySelect.singleResult();
        if(isInterest){
            if(interest==null){
                Interest newInterest = new Interest();
                newInterest.setActivityId(activityId);
                newInterest.setOwner(weixin);
                newInterest.setGmtCreate(new Date());
                jdbcDao.insert(newInterest);
                activity.setNumberOfInterest(activity.getNumberOfInterest()+1);
            }else {
                result.put(ResultConst.SUCCESS,false);
                result.put("count",activity.getNumberOfInterest());
                result.put(ResultConst.MESSAGE,"已收藏该活动");
                result.put("isInterest",true);
                return result;
            }
        }else {
            if(interest!=null){
                jdbcDao.delete(interest);
                activity.setNumberOfInterest(activity.getNumberOfInterest()-1);
            }else {
                result.put(ResultConst.SUCCESS,false);
                result.put("count",activity.getNumberOfInterest());
                result.put(ResultConst.MESSAGE,"未收藏该活动");
                result.put("isInterest",false);
                return result;
            }
        }
        jdbcDao.update(activity);
        ActivityVo activityVo = indexService.findActivityById(activityId);
        String oldWeixinStr = activityVo.getWeixinStrs();
        List<String> weixinStrArray;
        if(StringUtils.isNotBlank(oldWeixinStr)){
            weixinStrArray = new CopyOnWriteArrayList<>(activityVo.getWeixinStrs().split(","));
        }else {
            weixinStrArray = new ArrayList<>();
        }
        String weixinStrs ;
        if(isInterest){
            if(!weixinStrArray.contains(weixin)){
                weixinStrArray.add(weixin);
            }
        }else {
            for (String s : weixinStrArray) {
                if(StringUtils.equals(s,weixin)){
                    weixinStrArray.remove(s);
                    break;
                }
            }
        }
        weixinStrs = StringUtils.join(weixinStrArray,",");
        activityVo.setWeixinStrs(weixinStrs);
        Select<Activity> newActivitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        newActivitySelect.and("activityId",activityId);
        Activity newActivity = newActivitySelect.singleResult();
        activityVo.setNumberOfInterest(newActivity.getNumberOfInterest());
        indexService.updateActivityIndex(activityVo);
        result.put("isInterest",isInterest);
        result.put("count",activity.getNumberOfInterest());
        result.put(ResultConst.SUCCESS,true);
        return result;
    }

    private void initActivityVoUploads(ActivityVo activityVo,String uploadFileIds){
        String[] uploadStrs = uploadFileIds.split(",");
        List<UploadFileVo> fileVos = new ArrayList<>();
        for (int i=0;i<uploadStrs.length;i++){
            if(StringUtils.isNotBlank(uploadStrs[i])){
                Select<UploadFile> select = jdbcDao.createSelect(UploadFile.class).where("1",1);
                select.and("uploadFileId",Long.valueOf(uploadStrs[i]));
                UploadFile uploadFile = select.singleResult();
                if(uploadFile==null){
                    continue;
                }
                fileVos.add(BeanKit.convert(new UploadFileVo(),uploadFile));
            }
        }
        activityVo.setUploadFileVos(fileVos);
    }

    @Override
    public void add(ActivityVo activityVo, String uploadFileIds) {
        initActivityVoUploads(activityVo,uploadFileIds);
        Verifier.init().notEmpty(activityVo.getName(), "标题").notEmpty(activityVo.getActivityAreaVo().getAreaName(),"所属活动点")
        .notEmpty(activityVo.getBrief(),"简述").maxLength(activityVo.getName(),100,"标题")
                .maxLength(activityVo.getBrief(),200,"简介").notNull(activityVo.getBeginDate(),"开始时间")
                .notNull(activityVo.getEndDate(),"结束时间").validate();
        if(activityVo.getEndDate().getTime()<=activityVo.getBeginDate().getTime()){
            throw new ImesneException("开始时间应早于结束时间");
        }
        //设置活动点
        Select<ActivityArea> activityAreaSelect = jdbcDao.createSelect(ActivityArea.class).where("1",1);
        activityAreaSelect.and("areaName",activityVo.getActivityAreaVo().getAreaName());
        ActivityArea activityArea = activityAreaSelect.singleResult();
        if(activityArea==null){
            throw new ImesneException("活动点不存在");
        }
        activityVo.setActivityAreaId(activityArea.getActivityAreaId());
        String userName = HttpUtils.getLoginUser().getUsername();
        Date date = new Date();
        activityVo.setGmtCreate(date);
        activityVo.setCreator(userName);
        activityVo.setModifier(userName);
        activityVo.setGmtModify(date);
        activityVo.setEnable(false);
        Activity activity = BeanKit.convert(new Activity(),activityVo);
        activity.setNumberOfInterest(0L);
        activity.setNumberOfClick(0L);
        Long activityId = (Long) jdbcDao.insert(activity);
        //将图片和活动关联起来
        BizUploadFile bizUploadFile = new BizUploadFile();
        bizUploadFile.setBizId(activityId);
        bizUploadFile.setBizType(BizUploadFileType.ACTIVITY.getCode());
        //插入业务文件
        Long insert = (Long)jdbcDao.insert(bizUploadFile);
        bizUploadFile.setBizUploadFileId(insert);
        String[] uploadFiles = uploadFileIds.split(",");
        long order = 1;
        for(int i=0;i<uploadFiles.length;i++){
            if(StringUtils.isNotBlank(uploadFiles[i])){
                Select<UploadFile> select = jdbcDao.createSelect(UploadFile.class).where("1",1);
                select.and("uploadFileId",Long.valueOf(uploadFiles[i]));
                UploadFile uploadFile = select.singleResult();
                if(bizUploadFile==null){
                    throw new ImesneException("找不到图片");
                }
                uploadFile.setBizUploadFileId(bizUploadFile.getBizUploadFileId());
                uploadFile.setOrd(order);
                jdbcDao.update(uploadFile);
                order++;
            }
        }

    }

    @Override
    public void deleteByIds(Long[] activityIds) {
        Verifier.init().notEmpty(activityIds, "id").validate();
        for(int i=0;i<activityIds.length;i++){
            //删除感兴趣
            Select<Interest> interestSelect = jdbcDao.createSelect(Interest.class).where("1",1);
            interestSelect.and("activityId",activityIds[i]);
            List<Interest> interests = interestSelect.list();
            for (Interest interest : interests) {
                jdbcDao.delete(interest);
            }
            //删除图片
            Select<BizUploadFile> bizUploadFileSelect = jdbcDao.createSelect(BizUploadFile.class).where("1",1);
            bizUploadFileSelect.and("bizType",BizUploadFileType.ACTIVITY.getCode());
            bizUploadFileSelect.and("bizId",activityIds[i]);
            BizUploadFile bizUploadFile = bizUploadFileSelect.singleResult();
            if(bizUploadFile!=null){
                Select<UploadFile> uploadFileSelect = jdbcDao.createSelect(UploadFile.class).where("1",1);
                uploadFileSelect.and("bizUploadFileId",bizUploadFile.getBizUploadFileId());
                List<UploadFile> uploadFiles = uploadFileSelect.list();
                for(UploadFile uploadFile:uploadFiles){
                    jdbcDao.delete(uploadFile);
                }
                jdbcDao.delete(bizUploadFile);
            }
            Activity activity = new Activity();
            activity.setActivityId(activityIds[i]);
            jdbcDao.delete(activity);
        }
        for(int i=0;i<activityIds.length;i++){
            indexService.deleteIndex(String.valueOf(activityIds[i]), IndexType.ACTIVITY.getCode());
        }
    }

    @Override
    public void enable(Long activityId) {
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        activitySelect.and("activityId",activityId);
        Activity activity = activitySelect.singleResult();
        activity.setEnable(activity.isEnable()?false:true);
        activity.setGmtModify(new Date());
        activity.setModifier(HttpUtils.getLoginUser().getUsername());
        jdbcDao.update(activity);
        if(StringUtils.equals(activity.getStatus(),ActivityStatus.ISSUERED.getCode())){
            ActivityVo activityVo = completeActivityIndexVo(BeanKit.convert(new ActivityVo(),activity));
            activityVo.setFirstPicUrl(findActivityFirstPicUrl(activityId));
            indexService.updateActivityIndex(activityVo);
        }

    }

    /**
     * 补全索引类
     * @param activityVo
     */
    private ActivityVo completeActivityIndexVo(ActivityVo activityVo){
        Select<ActivityArea> activityAreaSelect = jdbcDao.createSelect(ActivityArea.class).where("1",1);
        activityAreaSelect.and("activityAreaId",activityVo.getActivityAreaId());
        ActivityArea activityArea = activityAreaSelect.singleResult();
        if(activityArea!=null){
            activityVo.setLatitude(activityArea.getLatitude());
            activityVo.setLongitude(activityArea.getLongitude());
            activityVo.setActivityAreaEnable(activityArea.isEnable());
            activityVo.setActivityAreaStatus(activityArea.getStatus());
        }
        ActivityVo indexActivityVo = indexService.findActivityById(activityVo.getActivityId());
        if(indexActivityVo!=null){
            activityVo.setWeixinStrs(indexActivityVo.getWeixinStrs());
        }else {
            activityVo.setWeixinStrs("");
        }
        return activityVo;
    }

    @Override
    public void update(ActivityVo activityVo,String uploadFileIds) {
        initActivityVoUploads(activityVo,uploadFileIds);
        Verifier.init().notEmpty(activityVo.getName(), "标题").notEmpty(activityVo.getActivityAreaVo().getAreaName(),"所属活动点")
                .notEmpty(activityVo.getBrief(),"简述").maxLength(activityVo.getName(),100,"标题")
                .maxLength(activityVo.getBrief(),200,"简介").notNull(activityVo.getBeginDate(),"开始时间")
                .notNull(activityVo.getEndDate(),"结束时间").validate();
        if(activityVo.getEndDate().getTime()<=activityVo.getBeginDate().getTime()){
            throw new ImesneException("开始时间应早于结束时间");
        }
        //设置活动点
        Select<ActivityArea> activityAreaSelect = jdbcDao.createSelect(ActivityArea.class).where("1",1);
        activityAreaSelect.and("areaName",activityVo.getActivityAreaVo().getAreaName());
        ActivityArea activityArea = activityAreaSelect.singleResult();
        if(activityArea==null){
            throw new ImesneException("活动点不存在");
        }else {
            activityVo.setActivityAreaId(activityArea.getActivityAreaId());
        }
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        activitySelect.and("activityId",activityVo.getActivityId());
        Activity activity = activitySelect.singleResult();
        if(!StringUtils.equals(activity.getName(),activityVo.getName())){
            Select<Activity> activitySelect1 = jdbcDao.createSelect(Activity.class).where("1",1);
            activitySelect1.and("name",activityVo.getName());
            Activity activity1 = activitySelect1.singleResult();
            if(activity1!=null&&(activity1.getActivityId()!=activityVo.getActivityId())){
                throw new ImesneException("活动标题重复");
            }
        }
        String oldStatus = activity.getStatus();
        String newStaus = activityVo.getStatus();
        updateActivityToVo(activity,activityVo);
        Date date = new Date();
        activity.setGmtModify(date);
        if(StringUtils.equals(activityVo.getStatus(),ActivityStatus.ISSUERED.getCode())){
            activity.setGmtIssue(date);
            activity.setIssuer(HttpUtils.getLoginUser().getUsername());
        }
        jdbcDao.update(activity);
        //更新活动的图片
        String[] newUploadFiles = uploadFileIds.split(",");
        //获取原先绑定的图片
        Select<BizUploadFile> bizUploadFileSelect = jdbcDao.createSelect(BizUploadFile.class).where("1",1);
        bizUploadFileSelect.and("bizId",activity.getActivityId());
        bizUploadFileSelect.and("bizType",BizUploadFileType.ACTIVITY.getCode());
        BizUploadFile bizUploadFile = bizUploadFileSelect.singleResult();
        Select<UploadFile> uploadFileSelect = jdbcDao.createSelect(UploadFile.class).where("1",1);
        uploadFileSelect.and("bizUploadFileId",bizUploadFile.getBizUploadFileId());
        List<UploadFile> oldUploadFiles = uploadFileSelect.list();
        long order = 1;
        String firstPicUrl = "";
        for(int i=0;i<newUploadFiles.length;i++){
            if(StringUtils.isBlank(newUploadFiles[i])){
                continue;
            }
            boolean create = true;
            for(UploadFile uploadFile:oldUploadFiles){
                if(uploadFile.getUploadFileId().longValue()==Long.valueOf(newUploadFiles[i]).longValue()){
                    create = false;
                    uploadFile.setOrd(order);
                    jdbcDao.update(uploadFile);
                    oldUploadFiles.remove(uploadFile);
                    break;
                }
            }
            if(create){
                Select<UploadFile> uploadFileSelect1 = jdbcDao.createSelect(UploadFile.class).where("1",1);
                uploadFileSelect1.and("uploadFileId",Long.valueOf(newUploadFiles[i]));
                UploadFile uploadFile = uploadFileSelect1.singleResult();
                if(uploadFile==null){
                    throw new ImesneException("图片有误");
                }
                uploadFile.setOrd(order);
                uploadFile.setBizUploadFileId(bizUploadFile.getBizUploadFileId());
                jdbcDao.update(uploadFile);
            }
            if(order==1){
                firstPicUrl=newUploadFiles[i];
            }
            order++;
        }
        //删除原先的多余图片
        for(UploadFile uploadFile:oldUploadFiles){
            jdbcDao.delete(uploadFile);
        }

        ActivityVo activityVo1 = BeanKit.convert(new ActivityVo(),activity);
        activityVo1.setFirstPicUrl(firstPicUrl);
        if(StringUtils.equals(oldStatus,ActivityStatus.ISSUERED.getCode())){
            if(!StringUtils.equals(newStaus,ActivityStatus.ISSUERED.getCode())){
                indexService.deleteIndex(String.valueOf(activity.getActivityId()),IndexType.ACTIVITY.getCode());
            }else {
                indexService.updateActivityIndex(completeActivityIndexVo(activityVo1));
            }
        }else {
            if(StringUtils.equals(newStaus,ActivityStatus.ISSUERED.getCode())){
                indexService.addActivityIndex(completeActivityIndexVo(activityVo1));
            }
        }

    }

    @Override
    public void doAudit(ActivityVo activityVo) {
        if(StringUtils.equals(activityVo.getStatus(),ActivityStatus.REVIEWREFUSED.getCode())){
            Verifier.init().notEmpty(activityVo.getReason().trim(),"审核失败原因").validate();
        }
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        activitySelect.and("activityId",activityVo.getActivityId());
        Activity activity = activitySelect.singleResult();
        if(activity==null){
            throw new ImesneException("找不到该活动");
        }
        Date date = new Date();
        if(StringUtils.equals(activityVo.getStatus(),ActivityStatus.REVIEWED.getCode())){
            activity.setStatus(ActivityStatus.REVIEWED.getCode());
            activity.setReason("");
        }else {
            activity.setStatus(ActivityStatus.REVIEWREFUSED.getCode());
            activity.setReason(activityVo.getReason());
        }
        activity.setAuditor(HttpUtils.getLoginUser().getUsername());
        activity.setGmtAudit(date);
        jdbcDao.update(activity);
//        if(StringUtils.equals(activityVo.getStatus(),ActivityStatus.REVIEWED.getCode())){
//            ActivityVo activityVo1 = BeanKit.convert(new ActivityVo(),activity);
//            activityVo1.setFirstPicUrl(findActivityFirstPicUrl(activity.getActivityId()));
//            indexService.addActivityIndex(activityVo1);
//        }
    }

    public String findActivityFirstPicUrl(Long activityId){
        Select<BizUploadFile> bizUploadFileSelect = jdbcDao.createSelect(BizUploadFile.class).where("1",1);
        bizUploadFileSelect.and("bizType",BizUploadFileType.ACTIVITY.getCode());
        bizUploadFileSelect.and("bizId",activityId);
        BizUploadFile bizUploadFile = bizUploadFileSelect.singleResult();
        if(bizUploadFile==null){
            return "";
        }
        Select<UploadFile> uploadFileSelect = jdbcDao.createSelect(UploadFile.class).where("1",1);
        uploadFileSelect.and("bizUploadFileId",bizUploadFile.getBizUploadFileId());
        uploadFileSelect.and("ord",1);
        UploadFile uploadFile = uploadFileSelect.singleResult();
        if(uploadFile==null){
            return "";
        }else {
            return uploadFile.getFileUrl();
        }
    }

	@Override
	public List<ActivityVo> searchActivity (SearchVo searchVo) {

        BooleanQuery booleanQuery = new BooleanQuery();
        List<Document> documentList=new ArrayList<> ();
        List<ActivityVo> activityVos=new ArrayList<> ();
        try {

            //活动审核通过
            Query queryStatus = new TermQuery(new Term ("status", ActivityStatus.ISSUERED.getCode ()));
            booleanQuery.add (queryStatus, BooleanClause.Occur.MUST);
            //活动启用
            Query queryEnabel = new TermQuery(new Term ("enable", "true"));
            booleanQuery.add (queryEnabel, BooleanClause.Occur.MUST);


            //活动点审核通过
            Query queryActivityAreaStatus = new TermQuery(new Term ("activityAreaStatus", ActivityAreaStatus.ISSUERED.getCode ()));
            booleanQuery.add (queryActivityAreaStatus, BooleanClause.Occur.MUST);
            //活动点启用
            Query queryActivityAreaEnabel = new TermQuery(new Term ("activityAreaEnable", "true"));
            booleanQuery.add (queryActivityAreaEnabel, BooleanClause.Occur.MUST);


            //索引类型为活动
            Query queryIndexType = new TermQuery(new Term ("indexType", IndexType.ACTIVITY.getCode ()));
            booleanQuery.add (queryIndexType, BooleanClause.Occur.MUST);

            //发布时间 取今天之前的数据
            Query gmtIssue= NumericRangeQuery.newLongRange ("gmtIssue", 0L, new Date ().getTime (), true, true);
            booleanQuery.add (gmtIssue, BooleanClause.Occur.MUST);

            if (searchVo.getXleft () != 0 && searchVo.getXright () != 0) {
                //经度
                Query xQuery = NumericRangeQuery.newDoubleRange ("longitude", searchVo.getXleft (), searchVo.getXright (), true, true);
                booleanQuery.add (xQuery, BooleanClause.Occur.MUST);
            }

            if (searchVo.getYright () != 0 && searchVo.getYleft () != 0) {
                //纬度
                Query yQuery = NumericRangeQuery.newDoubleRange ("latitude", searchVo.getYright (), searchVo.getYleft (), true, true);
                booleanQuery.add (yQuery, BooleanClause.Occur.MUST);
            }

            //条件：关键字
            if (StringUtils.isNotEmpty (searchVo.getKeyword ())) {

                MultiFieldQueryParser parser = new MultiFieldQueryParser (LuceneContext.getInstance ().getVersion (),
                        new String[]{"name", "brief"}, LuceneContext.getInstance ().getAnalyzer ());
                Query keywordQuery = parser.parse (searchVo.getKeyword ());

                booleanQuery.add (keywordQuery, BooleanClause.Occur.MUST);

                //查询关键字 存储
                applicationContext.publishEvent(new MemberEvent.AddToSearchKey (searchVo.getKeyword ()));

            }

            //条件：活动点ID
            if (searchVo.getActivityAreaId ()!=null) {
                Query activityAreaIdQuery= NumericRangeQuery.newLongRange ("activityAreaId", searchVo.getActivityAreaId (), searchVo.getActivityAreaId (), true, true);
                booleanQuery.add (activityAreaIdQuery, BooleanClause.Occur.MUST);
            }

            //条件：时间范围
            if (searchVo.getBeginTime ()!=null&& searchVo.getEndTime ()!=null){

                Query beginDateQuery= NumericRangeQuery.newLongRange ("beginDate", Long.MIN_VALUE, searchVo.getEndTime ().getTime (), false, true);
                Query endDateQuery= NumericRangeQuery.newLongRange ("endDate", searchVo.getBeginTime ().getTime (), Long.MAX_VALUE, true, false);

                booleanQuery.add (beginDateQuery, BooleanClause.Occur.MUST);
                booleanQuery.add (endDateQuery, BooleanClause.Occur.MUST);

            }

            //条件：活动类型、标签
            if (StringUtils.isNotEmpty (searchVo.getActivityLabel ())) {
                MultiFieldQueryParser parser = new MultiFieldQueryParser (LuceneContext.getInstance ().getVersion (),
                        new String[]{"activityLabel"}, LuceneContext.getInstance ().getAnalyzer ());
                Query activityLabelQuery = parser.parse (searchVo.getActivityLabel ());

                booleanQuery.add (activityLabelQuery, BooleanClause.Occur.MUST);
            }

            //条件:微信号
            if (BooleanUtils.isTrue (searchVo.getSearchInterest ())&&StringUtils.isNotEmpty (searchVo.getWeixin ())){
                MultiFieldQueryParser parser = new MultiFieldQueryParser (LuceneContext.getInstance ().getVersion (),
                        new String[]{"weixinStrs"}, LuceneContext.getInstance ().getAnalyzer ());
                Query weixinStrsQuery = parser.parse (searchVo.getWeixin ());
                booleanQuery.add (weixinStrsQuery, BooleanClause.Occur.MUST);
            }

            //排序
            Sort sort=new Sort();
            if (StringUtils.isEmpty (searchVo.getSortType ())||StringUtils.equals (SortType.WEIGHT_SORT.getCode (),searchVo.getSortType ())) {
                //权重排序
                SortField weightSortField=new SortField("weight", SortField.LONG,true);
                sort.setSort (weightSortField);
            }else if(StringUtils.equals (SortType.INTEREST_SORT.getCode (),searchVo.getSortType ())) {
                //人气排序
                SortField numberOfInterestSortField = new SortField ("numberOfInterest", SortField.LONG, true);
                sort.setSort (numberOfInterestSortField);
            }


            IndexSearcher searcher = LuceneContext.getInstance ().getSearcher ();

            //查询所有
            TopDocs docs = searcher.search (booleanQuery, Integer.MAX_VALUE,sort);

            //分页处理
            Integer start = (searchVo.getPageNum () - 1) * searchVo.getPageSize ();
            Integer end = Math.min(start +  searchVo.getPageSize (), docs.totalHits);
            if (start > docs.totalHits) {
                return new ArrayList<>();
            }

            ScoreDoc[] scoreDocs = docs.scoreDocs;

            //距离排序
            if(StringUtils.equals (SortType.DISTANCE_SORT.getCode (),searchVo.getSortType ())){

                for (ScoreDoc scoreDoc : scoreDocs) {
                    Document hitDoc = searcher.doc(scoreDoc.doc);
                    documentList.add (hitDoc);
                }
                List<ActivityVo > allActivityVos = IndexUtils.docs2ActivityList (documentList);
                DistanceSortComparator distanceSortComparator=new DistanceSortComparator (searchVo.getXnow (),searchVo.getYnow ());
                Collections.sort (allActivityVos,distanceSortComparator);

                for (int i = start; i < end; i++) {
                    activityVos.add ( allActivityVos.get (i));
                }

            }else {
                for (int i = start; i < end; i++) {
                    ScoreDoc hit = scoreDocs[i];
                    Document hitDoc = searcher.doc(hit.doc);
                    documentList.add (hitDoc);
                }
                activityVos = IndexUtils.docs2ActivityList (documentList);
            }

        } catch (ParseException | IOException e) {
            e.printStackTrace ();
        }


        if (StringUtils.isNotEmpty (searchVo.getWeixin ())){

            for (ActivityVo activityVo : activityVos) {

                if (StringUtils.contains (activityVo.getWeixinStrs (),searchVo.getWeixin ())) {
                    activityVo.setInterest (true);
                }

            }

        }


        return activityVos;
	}

    @Override
    public List<ActivityVo> findAllActivityInIndex () {
        BooleanQuery booleanQuery = new BooleanQuery();
        List<Document> documentList=new ArrayList<> ();

        //活动审核通过
        Query queryStatus = new TermQuery(new Term ("status", ActivityStatus.ISSUERED.getCode ()));
        booleanQuery.add (queryStatus, BooleanClause.Occur.MUST);
        //活动启用
        Query queryEnabel = new TermQuery(new Term ("enable", "true"));
        booleanQuery.add (queryEnabel, BooleanClause.Occur.MUST);


        //活动点审核通过
        Query queryActivityAreaStatus = new TermQuery(new Term ("activityAreaStatus", ActivityAreaStatus.ISSUERED.getCode ()));
        booleanQuery.add (queryActivityAreaStatus, BooleanClause.Occur.MUST);
        //活动点启用
        Query queryActivityAreaEnabel = new TermQuery(new Term ("activityAreaEnable", "true"));
        booleanQuery.add (queryActivityAreaEnabel, BooleanClause.Occur.MUST);


        //索引类型为活动
        Query queryIndexType = new TermQuery(new Term ("indexType", IndexType.ACTIVITY.getCode ()));
        booleanQuery.add (queryIndexType, BooleanClause.Occur.MUST);

        //发布时间 取今天之前的数据
        Query gmtIssue= NumericRangeQuery.newLongRange ("gmtIssue", 0L, new Date ().getTime (), true, true);
        booleanQuery.add (gmtIssue, BooleanClause.Occur.MUST);

        try {
            IndexSearcher searcher = LuceneContext.getInstance ().getSearcher ();

            TopDocs docs  = searcher.search (booleanQuery,Integer.MAX_VALUE);

            for (ScoreDoc scoreDoc : docs.scoreDocs) {

                Document document=searcher.doc (scoreDoc.doc);

                documentList.add (document);
            }

        } catch (IOException e) {
            e.printStackTrace ();
        }

        List<ActivityVo> activityVos = IndexUtils.docs2ActivityList (documentList);

        return activityVos;
    }


    private static class DistanceSortComparator implements Comparator{

        private Double x;
        private Double y;

        public DistanceSortComparator () {
        }

        public DistanceSortComparator (Double lng,Double lat) {
            x=lng;
            y=lat;
        }


        @Override
        public int compare (Object o1, Object o2) {

            ActivityVo v1=(ActivityVo) o1;
            ActivityVo v2=(ActivityVo) o2;

            int d1= (new   Double(DistanceUtils.getDistance (x,y,v1.getLongitude (),v1.getLatitude ()))).intValue();
            int d2= (new   Double(DistanceUtils.getDistance (x,y,v2.getLongitude (),v2.getLatitude ()))).intValue();

            return d1-d2;
        }
    }



    @Override
    public List<ActivityVo> findAllEnable() {
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        activitySelect.and("status",ActivityStatus.ISSUERED.getCode());
        List<ActivityVo> activityVos = BeanKit.convert(ActivityVo.class,activitySelect.list());
        for (ActivityVo activityVo : activityVos) {
            activityVo.setFirstPicUrl(findActivityFirstPicUrl(activityVo.getActivityId()));
            completeActivityIndexVo(activityVo);
            Select<Interest> interestSelect = jdbcDao.createSelect(Interest.class).where("1",1);
            interestSelect.and("activityId",activityVo.getActivityId());
            List<Interest> interests = interestSelect.list();
            StringBuilder interstWeixinStrs = new StringBuilder();
            for (Interest interest : interests) {
                interstWeixinStrs.append(interest.getOwner()).append(",");
            }
            if (interstWeixinStrs.length()>0){
                interstWeixinStrs.deleteCharAt(interstWeixinStrs.length()-1);
            }
            activityVo.setWeixinStrs(interstWeixinStrs.toString());
        }
        return activityVos;
    }

    private void updateActivityToVo(Activity activity,ActivityVo activityVo){
        Date date = new Date();
        activity.setActivityAreaId(activityVo.getActivityAreaId());
        activity.setActivityLabel(activityVo.getActivityLabel());
        activity.setBeginDate(activityVo.getBeginDate());
        activity.setEndDate(activityVo.getEndDate());
        activity.setBrief(activityVo.getBrief());
        activity.setCharging(activityVo.getCharging());
        activity.setGmtModify(date);
        activity.setModifier(HttpUtils.getLoginUser().getUsername());
        activity.setContent(activityVo.getContent());
        activity.setName(activityVo.getName());
        activity.setRecommended(activityVo.getRecommended());
        activity.setStatus(activityVo.getStatus());
        activity.setTelephone(activityVo.getTelephone());
        activity.setTicketUrl(activityVo.getTicketUrl());
    }

    /**
     * 设置活动图片
     * @param activityVo
     */
    public void setActivityUploadFiles(ActivityVo activityVo){
        //获取图片
        Select<BizUploadFile> bizUploadFileSelect = jdbcDao.createSelect(BizUploadFile.class).where("1",1);
        bizUploadFileSelect.and("bizType", BizUploadFileType.ACTIVITY.getCode());
        bizUploadFileSelect.and("bizId",activityVo.getActivityId());
        BizUploadFile bizUploadFile = bizUploadFileSelect.singleResult();
        if(bizUploadFile==null){
            return;
        }
        Select<UploadFile> uploadFileSelect = jdbcDao.createSelect(UploadFile.class).where("1",1);
        uploadFileSelect.and("bizUploadFileId",bizUploadFile.getBizUploadFileId());
        uploadFileSelect.orderBy("ord").asc();
        List<UploadFile> uploadFiles = uploadFileSelect.list();
        if(CollectionUtils.isNotEmpty(uploadFiles)){
            activityVo.setUploadFileVos(BeanKit.convert(UploadFileVo.class,uploadFiles));
        }
    }

    @Override
    public ActivityVo mobileFindById(Long activityId, String weixin) {
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        activitySelect.and("activityId",activityId);
        Activity activity = activitySelect.singleResult();
        activity.setNumberOfClick(activity.getNumberOfClick()+1);
        jdbcDao.update(activity);

        Select<ActivityArea> activityAreaSelect = jdbcDao.createSelect(ActivityArea.class).where("1",1);
        activityAreaSelect.and("activityAreaId",activity.getActivityAreaId());
        ActivityAreaVo activityAreaVo = BeanKit.convert(new ActivityAreaVo(), activityAreaSelect.singleResult());
        ActivityVo activityVo = BeanKit.convert(new ActivityVo(),activity);
        activityVo.setActivityAreaVo(activityAreaVo);
        //获取报名单信息
        List<ActivityEnrollVo> activityEnrollVos = activityEnrollService.findByActivityId(activityId);
        activityVo.setActivityEnrollVos(activityEnrollVos);

        Select<Interest> interestSelect = jdbcDao.createSelect(Interest.class).where("1",1);
        interestSelect.and("activityId",activityId);
        interestSelect.and("owner",weixin);
        Interest interest = interestSelect.singleResult();
        if(interest==null){
            activityVo.setInterest(false);
        }else {
            activityVo.setInterest(true);
        }
        setActivityUploadFiles(activityVo);
        if(activityVo.getUploadFileVos().size()>0){
            activityVo.setFirstPicUrl(activityVo.getUploadFileVos().get(0).getFileUrl());
        }else {
            activityVo.setFirstPicUrl("");
        }
        indexService.updateActivityIndex(completeActivityIndexVo(activityVo));
        return activityVo;
    }

    @Override
    public boolean existActivityName(String name) {
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        activitySelect.and("name",name);
        Activity activity = activitySelect.singleResult();
        if(activity==null){
            return false;
        }else {
            return true;
        }
    }

    @Override
    public void dealActivityInterest(List<ActivityVo> activityVos,String weixin) {
        Set<Long> interstActivityStrs = new HashSet<>();
        Select<Interest> interestSelect = jdbcDao.createSelect(Interest.class).where("1",1);
        interestSelect.and("owner",weixin);
        List<Interest> interests = interestSelect.list();
        for (Interest interest : interests) {
            interstActivityStrs.add(interest.getActivityId());
        }
        for (ActivityVo activityVo : activityVos) {
            if(interstActivityStrs.contains(activityVo.getActivityId())){
                activityVo.setInterest(true);
            }else {
                activityVo.setInterest(false);
            }
        }
    }

    @Override
    public void IssuerActivityArea(ActivityVo activityVo) {
        Long activityId = activityVo.getActivityId();
        Date gmtIssuer = activityVo.getGmtIssue();
        String issuer = activityVo.getIssuer();
        Verifier.init().notNull(activityId,"活动Id").notNull(gmtIssuer,"发布时间").notBlank(issuer,"发布人").validate();
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1",1);
        activitySelect.and("activityId",activityId);
        Activity activity = activitySelect.singleResult();
        activity.setEnable(true);
        if(activity==null){
            throw new ImesneException("活动不存在");
        }
        if(StringUtils.equals(activity.getStatus(),ActivityStatus.ISSUERED.getCode())){
            throw new ImesneException("活动已经发布过");
        }
        activity.setIssuer(issuer);
        activity.setGmtIssue(gmtIssuer);
        activity.setStatus(ActivityStatus.ISSUERED.getCode());
        jdbcDao.update(activity);
        ActivityVo activityVo1 = BeanKit.convert(new ActivityVo(),activity);
        activityVo1.setFirstPicUrl(findActivityFirstPicUrl(activity.getActivityId()));
        indexService.addActivityIndex(completeActivityIndexVo(activityVo1));
    }

    @Override
    public List<ActivityVo> nameFilter(ActivityVo activityVo) {
        Select<Activity> activitySelect = jdbcDao.createSelect(Activity.class).where("1", 1);
        activitySelect.and("name","like",new Object[]{"%"+activityVo.getName()+"%"});
        PageList<Activity> pageList = activitySelect.pageList(activityVo);
        List<ActivityVo> result = BeanKit.convert(ActivityVo.class,pageList);
        return result;
    }
}
